package sqlitedb

import (
	"errors"
	"fmt"
	"strconv"
	"time"

	us "gitee.com/gouyabin/go_utils"
)

//数据库名称与表结构+增删改查
const (
	UserDataDB = "User"
)

type User struct {
	Id             int    `sqlField:"id" sqlType:"integer PRIMARY KEY autoincrement" json:"id,omitempty"` //ID主键
	UserName       string `sqlField:"username" sqlType:"CHAR(32)" json:"username,omitempty"`
	CUserName      string `sqlField:"cusername" sqlType:"CHAR(32)" json:"cusername,omitempty"`
	PassWord       string `sqlField:"password" sqlType:"CHAR(32)" json:"password,omitempty"`
	Email          string `sqlField:"email" sqlType:"CHAR(32)" json:"email,omitempty"`
	PhoneNumber    string `sqlField:"phonenumber" sqlType:"CHAR(32)" json:"phonenumber,omitempty"`
	CTime          string `sqlField:"ctime" sqlType:"CHAR(32)" json:"ctime,omitempty"`
	ActivityStatus int    `sqlField:"astatus" sqlType:"INT" json:"astatus,omitempty"`
	AuthStr        string `sqlField:"authstr" sqlType:"CHAR(32)" json:"authstr,omitempty"`         //认证字符串
	AuthOverTime   int64  `sqlField:"authovertime" sqlType:"BIGINT" json:"authovertime,omitempty"` //认证字符串超时时间 unxi time
	UserOverTime   int64  `sqlField:"userovertime" sqlType:"BIGINT" json:"userovertime,omitempty"`
	LastLoginTime  string `sqlField:"lastlogintime" sqlType:"BIGINT" json:"lastlogintime,omitempty"`
	LastLoginIP    string `sqlField:"lastloginip" sqlType:"BIGINT" json:"lastloginip,omitempty"`
}

//设置 auth
func (*User) SetAuth(user, day string) (int, string, string) {
	//day 取值范围 1~365,
	db := CONN
	sqlCmd := "SELECT id,username,astatus FROM " + UserDataDB + " where username=\"" + user + "\""
	rows, err := db.Query(sqlCmd)
	if err != nil {
		us.CheckErr(err)
	}
	defer rows.Close()
	smsAll := []User{}
	for rows.Next() {
		p := new(User)
		err := rows.Scan(&p.Id, &p.UserName, &p.ActivityStatus)
		us.CheckErr(err)
		smsAll = append(smsAll, *p)
	}
	StateInt := isUserState(smsAll, false)
	userId := strconv.Itoa(smsAll[0].Id)
	if StateInt != 0 {
		return StateInt, "", ""
	}
	sdate, err := strconv.Atoi(day)
	us.CheckErr(err)
	nowTime := time.Now().Unix()
	sNow := time.Now().Unix() + int64(86400*sdate)
	sAuth := us.RandChar(64)
	stmt, err := db.Prepare("UPDATE " + UserDataDB + " SET authstr = ?,authovertime = ? ,lastlogintime = ? WHERE username = ?")
	us.CheckErr(err)
	_, err = stmt.Exec(sAuth, sNow, nowTime, user)
	us.CheckErr(err)
	return 0, sAuth, userId
}

//验证auth
func (*User) CheckAuth(key string) (int, User) {
	// errCode 0 正常 1025 没有查找到key 1026 账号已被删除 1027 未激活 1028 key不唯一 1029 key已经过期
	if key == "" {
		return 10012, User{}
	}
	db := CONN
	sqlCmd := "SELECT id,authovertime,astatus,username FROM " + UserDataDB + " where authstr=\"" + key + "\""
	fmt.Println("开始查找Auth", sqlCmd)
	rows, err := db.Query(sqlCmd)
	if err != nil {
		fmt.Println("SqliteDB 验证auth字符串错误,key:" + key)
		us.WriteLogV2("SqliteDB 验证auth字符串错误,key:" + key)
		fmt.Println(err)
		return 10099, User{}
	}
	defer rows.Close()
	smsAll := []User{}
	for rows.Next() {
		p := new(User)
		err := rows.Scan(&p.Id, &p.AuthOverTime, &p.ActivityStatus, &p.UserName)
		if err != nil {
			us.WriteLogV2("SqliteDB 数据取出错误")
			fmt.Println(err)
			us.CheckErr(err)
		} else {
			smsAll = append(smsAll, *p)
		}

	}
	// fmt.Println("smsAll", smsAll)
	StateInt := isUserState(smsAll, true)
	if StateInt == 0 {
		return 0, smsAll[0]
	}
	return StateInt, User{}
}

//验证密码
func (*User) CheckPasswd(user, passwd string) int {
	// errCode 0 正常 10001无用户 10002被删除 10003未激活 10009用户名不唯一 10015账号密码错误
	if user == "" || passwd == "" {
		return 10015
	}
	db := CONN
	sqlCmd := "SELECT id,password,astatus FROM " + UserDataDB + " where username=\"" + user + "\""
	fmt.Println("验证密码SqlCmd：", sqlCmd)
	rows, err := db.Query(sqlCmd)
	if err != nil {
		us.CheckErr(err)
	}
	defer rows.Close()
	smsAll := []User{}
	for rows.Next() {
		p := new(User)
		err := rows.Scan(&p.Id, &p.PassWord, &p.ActivityStatus)
		us.CheckErr(err)
		// fmt.Println(p.Id, p.passwd, p.IsState)
		smsAll = append(smsAll, *p)

	}
	StateInt := isUserState(smsAll, false)
	if StateInt == 0 {
		if smsAll[0].PassWord == passwd {
			return 0
		} else {
			return 10015
		}
	}
	return StateInt

}

//添加用户
func (u *User) Add() int64 {
	fmt.Println("添加用户")
	sqlCmd := "INSERT INTO " + UserDataDB + "(username, cusername, password,email,phonenumber,ctime,astatus,authstr,authovertime,userovertime,lastlogintime,lastloginip) values(?,?,?,?,?,?,?,?,?,?,?,?)"
	fmt.Println("sqlCmd:", sqlCmd)
	stmt, err := CONN.Prepare(sqlCmd)
	us.CheckErr(err)
	res, err := stmt.Exec(u.UserName, u.CUserName, u.PassWord, u.Email, u.PhoneNumber, u.CTime, u.ActivityStatus, u.AuthStr, u.AuthOverTime, u.UserOverTime, u.LastLoginTime, u.LastLoginIP)
	us.CheckErr(err)
	id, err := res.LastInsertId()
	us.CheckErr(err)
	fmt.Println(id)
	return id
}

//删除用户
func (*User) Del(u string) bool {
	fmt.Println("删除用户")
	stmt, err := CONN.Prepare("UPDATE " + UserDataDB + " SET astatus = ? WHERE username = ?")
	_, err = stmt.Exec(3, u)
	if err != nil {
		us.WriteLogV2(err.Error())
		return false
	}
	return true
}

//彻底删除用户
func (*User) DelCompletely(u string) {
	fmt.Println("彻底删除用户")
	sqlCmd := "delete from " + UserDataDB + " where username=?"
	stmt, err := CONN.Prepare(sqlCmd)
	us.CheckErr(err)
	res, err := stmt.Exec(u)
	us.CheckErr(err)
	affect, err := res.RowsAffected()
	us.CheckErr(err)
	fmt.Println(affect)
}

//获取用户信息
func (u *User) GetUserInfo(uname string) *User {
	fmt.Println("uname", uname)
	if uname == "" {
		return &User{}
	}
	db := CONN
	sqlCmd := "SELECT id,username,cusername,email,phonenumber,ctime,userovertime,lastlogintime ,lastloginip FROM " + UserDataDB + " where username=\"" + uname + "\""
	fmt.Println("开始查找id", sqlCmd)
	rows, err := db.Query(sqlCmd)
	if err != nil {
		fmt.Println("SqliteDB 查找id字符串错误,key:" + uname)
		us.WriteLogV2("SqliteDB 查找id字符串错误,key:" + uname)
		fmt.Println(err)
		return &User{}
	}
	defer rows.Close()
	DTypeAll := []User{}
	for rows.Next() {
		p := new(User)
		err := rows.Scan(&p.Id, &p.UserName, &p.CUserName, &p.Email, &p.PhoneNumber, &p.CTime, &p.UserOverTime, &p.LastLoginTime, &p.LastLoginIP)
		if err != nil {
			us.WriteLogV2("SqliteDB 数据取出错误")
			fmt.Println(err)
			us.CheckErr(err)
		} else {
			DTypeAll = append(DTypeAll, *p)
		}
	}
	if len(DTypeAll) <= 0 {
		return &User{}
	}
	return &DTypeAll[0]

}

//设置单独字段
func (u *User) SetOneInfo(uname, field, info string) error {
	if uname == "" || field == "" || info == "" {
		return errors.New("参数为空")
	}
	db := CONN
	stmt, err := db.Prepare("UPDATE " + UserDataDB + " SET " + field + " = ? WHERE username = ?")
	us.CheckErr(err)
	_, err = stmt.Exec(info, uname)
	if err != nil {
		return errors.New("更新数据失败")
	}
	return nil
}

//创建用户数据库
func createUserDB() {
	tableName := UserDataDB
	userTb := User{
		Id:             1,
		UserName:       "admin",
		CUserName:      "管理员",
		PassWord:       us.GetStringMd5("admin"),
		Email:          "admin@admin.org",
		PhoneNumber:    "+8613600000001",
		CTime:          "2020-10-16 15:38:34",
		ActivityStatus: 0,
		AuthStr:        "",
		AuthOverTime:   7,
		UserOverTime:   9999999999,
		LastLoginTime:  "2020-10-16 15:38:34",
		LastLoginIP:    "127.0.0.1",
	}
	fmt.Println("开始创建用户数据库", tableName)
	createTablesStruct(userTb, tableName)
	userTb.Add()
}

//判断用户状态
func isUserState(userList []User, isAuthOverTime bool) int {
	if len(userList) == 0 {
		return 10010
	}
	if len(userList) > 1 {
		return 10005
	}
	// 0:正常状态
	// 1:禁用状态
	// 2:未激活状态
	// 3:删除状态
	switch userList[0].ActivityStatus {
	case 1:
		return 10013
	case 2:
		return 10003
	case 3:
		return 10002
	case 0:
		if isAuthOverTime {
			if userList[0].AuthOverTime > time.Now().Unix() {
				return 0
			} else {
				return 10006
			}
		} else {
			return 0
		}

	}
	return 10014
}
